
#ifndef _NODE_H_
#define _NODE_H_

	// The class takes the type of element in the node and the
	// number of children this node is supposed to have
template <class e, int c, int n>
class Node 
{
	protected:
		e elem[n];
		Node* nodes[c];
		int filled;

	public:
		Node (e element);
		Node (e element, Node* n, ...);

		void SetElement (e element, int num);
		e Element(int num);
		e Element() { return Element(0); }

		void SetChild (int ChildNum, Node* node);
		Node<e,c,n>* Child (int ChildNum);
		Node<e,c,n>* operator [] (int ChildNum);

		Node<e,c,n>* left()  { return nodes[0]; }
		Node<e,c,n>* middle() { return nodes[c/2]; }
		Node<e,c,n>* right() { return nodes[c]; }

		Node<e,c,n>* next()  { return nodes[0]; }
		void SetNext (Node* node) { SetChild (0,node); }

		void SetFilled (int fill) { filled = fill; }
		int Filled () { return filled; }
};

template <class e, int c, int n>
Node<e,c,n> :: Node (e element)
{
	int i;

	// Set all the elements to the initial value passed
	for (i=0; i<n; i++)
		SetElement (element, i);

	// Now, fill the rest of the array with NULLs
	for (i=0; i<c; i++)
		SetChild (i, NULL);
}

template <class e, int c, int n>
Node<e,c,n> :: Node (e element, Node* n, ...)
{
	int i;
	// Set all the elements to the initial value passed
	for (i=0; i<n; i++)
		SetElement (element, i);

	// Now take care of the array
	va_list aptr;		// Variable array pointer
	void* tnode;

	// Put all the parameters sent into the array
	va_start (aptr, n);
	for (int i=0; i<c; i++)
	{
		tnode = va_arg (aptr, Node*);
		if ((int)tnode == -1)
			break;
		SetChild (i, (Node*)tnode);
	}
	va_end (aptr);
}

template <class e, int c, int n>
void Node<e,c,n> :: SetElement (e element, int num)
{
	elem[num] = element;
}

template <class e, int c, int n>
e Node<e,c,n> :: Element (int num)
{
	return elem[num];
}

template <class e, int c, int n>
void Node<e,c,n> :: SetChild (int ChildNum, Node* node)
{
	nodes[ChildNum] = node;
}

template <class e, int c, int n>
Node<e,c,n>* Node<e,c,n> :: Child (int ChildNum)
{
	return nodes[ChildNum];
}

template <class e, int c, int n>
Node<e,c,n>* Node<e,c,n> :: operator [] (int ChildNum)
{
	return Child (ChildNum);
}

#endif